home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / plugins / mapfindnonintegralfaces.py < prev    next >
Text File  |  2004-01-05  |  7KB  |  200 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. Finds faces that don't have three integral threepoints, or vertices that
  4. can be used as threepoints, and fixes them.  A preliminary of something that
  5. might go into QuArK 6.3e if it seems stable and useful enough, in spite
  6. of the supposed feature-freeze for Q6.3.  Maps created with 6.2 containing
  7. dragged around textures are likely to provide work for this plugin.
  8.  
  9. Puts Find Non-integral Faces commands on search menu; this produces a multiselection
  10.  of such faces
  11.  
  12. If a group has specific 'nonintegral' (value 1), then any non-integral faces it
  13.   contains will be ignored (maybe wanted for detail brushes, exotic decorations
  14.   or something).
  15.  
  16. Puts Integralize Faces command on commands menu; this forces very close threepoints
  17.   to integer, or uses integral vertexes as threepoints if possible.
  18.  
  19. """
  20. #
  21. # Copyright (C) 1996-2002 The QuArK Community
  22. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  23. # FOUND IN FILE "COPYING.TXT"
  24. #
  25.  
  26. #$Header: /cvsroot/quark/runtime/plugins/mapfindnonintegralfaces.py,v 1.5 2003/03/24 08:57:15 cdunde Exp $
  27.  
  28.  
  29.  
  30. Info = {
  31.    "plug-in":       "Find & fix non-integral faces",
  32.    "desc":          "finds faces that don't have three integral threepoints or vertices, tries to fix them",
  33.    "date":          "29 Dec 2002",
  34.    "author":        "tiglari",
  35.    "author e-mail": "tiglari@hexenworld.com",
  36.    "quark":         "Version 6.3c or later (**not** 6.2)" }
  37.  
  38.  
  39. from quarkpy.maputils import *
  40. import quarkpy.mapmenus
  41. import quarkpy.mapcommands
  42. import quarkpy.dlgclasses
  43.  
  44.  
  45. def is_integral_float(p):
  46.     if p==int(p):
  47.        return 1
  48.     debug(" p:  %s"%p)
  49.  
  50. def is_integral_vect(p):
  51.     if not is_integral_float(p.x):
  52.         return 0
  53.     if not is_integral_float(p.y):
  54.         return 0
  55.     if not is_integral_float(p.z):
  56.         return 0
  57.     return 1
  58.     
  59. SMALL = 0.0001
  60.  
  61. def oneof(v, vlist):
  62.     for v2 in vlist:
  63.         if abs(v-v2)<SMALL:
  64.             return 1
  65.  
  66. def inNonIntegralGroup(face):
  67.     parent = face.treeparent
  68.     while parent is not None:
  69.         if parent['nonintegral']:
  70.             return 1
  71.         parent = parent.treeparent
  72.  
  73. def findNonIntegralFaces(m):
  74.     editor=mapeditor()
  75.     if editor is None: return
  76.     results = []
  77.     for face in editor.Root.findallsubitems("",":f"):
  78.         if inNonIntegralGroup(face):
  79.             continue
  80.         icount = 0
  81.         threepoints = face.threepoints(0)
  82.         for p in threepoints:
  83.             if is_integral_vect(p):
  84.                 icount = icount+1
  85.         if icount<3:
  86.             debug("face %s, threepoints: %s"%(face.shortname, threepoints))
  87.             results.append(face)
  88.     if len(results)>0:
  89.         editor.layout.explorer.sellist=results
  90.         editor.invalidateviews()
  91.     else:
  92.         quarkx.msgbox("None found",MT_INFORMATION,MB_OK)
  93.         
  94.  
  95. def integralize_vect(v):
  96.     return quarkx.vect(round(v.x), round(v.y), round(v.z))
  97.  
  98. def integralizeFace(face):
  99.     points = []
  100.     #
  101.     # first make sure that it isn't OK as is
  102.     #
  103.     for p in face.threepoints(0):
  104.         if is_integral_vect(p):
  105.             points.append(p)
  106.     if len(points)==3:
  107.         return # no need to do anything so return nothing to do
  108.     #
  109.     # now see if a bit of forcing will do the trick
  110.     #
  111.     points = []
  112.     for p in face.threepoints(0):
  113.         intp = integralize_vect(p)
  114. #        debug('p: %s, intp: %s'%(p,intp))
  115.         if abs(p-intp)<SMALL:
  116.             points.append(intp)
  117.     newface = face.copy()
  118.     if len(points)<3:
  119.         #
  120.         # Now see if we have threepoint vertices that can be used
  121.         #
  122.         for vtxlist in face.vertices:
  123.             for vtx in vtxlist:
  124.                 debug('vtx: %s'%vtx)
  125.                 if is_integral_vect(vtx):
  126.                     if not oneof(vtx,points):
  127.                         debug(' appended')
  128.                         points.append(vtx)
  129.                 if len(points)==3:
  130.                     break
  131.         if len(points)<3:
  132.             debug(' not enough points')
  133.             return # can't do nothing so return nothing to do
  134.         d1 = points[1]-points[0]
  135.         d1.normalized
  136.         d2 = points[2]-points[0]
  137.         d2.normalized
  138.         length = abs(d1+d2)
  139.         if length<SMALL or math.fabs(2-length)<SMALL:
  140.             debug('colinear')
  141.             return # can't do anything because points colinear
  142.         normal=d1^d2
  143.         if abs(normal-face.normal)<SMALL:
  144.             newface.setthreepoints((points[0], points[1], points[2]), 0)
  145.         else:
  146.             newface.setthreepoints((points[0], points[2], points[1]), 0)
  147.     newface.setthreepoints(face.threepoints(2),2)
  148.     return newface
  149.         
  150.  
  151. def integralizeFaces(m):
  152.     editor=mapeditor()
  153.     if editor is None: return
  154.     undo=quarkx.action()
  155.     sel = editor.layout.explorer.sellist
  156.     if sel == []:
  157.         quarkx.msgbox("Nothing selected", MT_INFORMATION, MB_OK)
  158.         return
  159.     changed = []
  160.     for face in sel:
  161.         newface = integralizeFace(face)
  162.         if newface is not None:
  163.             changed.append(newface)
  164.             undo.exchange(face,newface)
  165.     if changed==[]:
  166.         quarkx.msgbox("Couldn't fix nuthin', all too hard", MT_INFORMATION, MB_OK)
  167.         return
  168.     editor.ok(undo, "integralize faces")
  169.     quarkx.msgbox("integralized %d faces"%len(changed), MT_INFORMATION, MB_OK)
  170.     editor.layout.explorer.sellist=changed
  171.     editor.invalidateviews()
  172.         
  173.  
  174.  
  175. quarkpy.mapsearch.items.append(qmenu.item('Find &Non-integral Faces', findNonIntegralFaces,
  176.  "|Find Non-integral Faces:\n\nThis finds faces that don't have integral threepoints.\n\nUse integralize Selected Faces on the command menu to try to automatically fix them.\n\nIf you want a particular group to be allowed to contain faces with non-integral threepoints, give it a nonintegral specific with a value such as 1.|intro.mapeditor.menu.html#searchmenu"))
  177.  
  178. quarkpy.mapcommands.items.append(qmenu.item('Integralize Selected Faces', integralizeFaces,
  179.  "|Integralize Selected Faces:\n\nIf faces without integral threepoints have enough integral vertices to be used as threepoints, changes the face to use them (also forces nearly integral ones).\n\nSelects the ones it changes, for checking.\n\nUse Find Non-integral Faces on the search menu to find suitable victims.\n\nResearch and fix the remaining ones by hand.|intro.mapeditor.menu.html#orientation"))
  180.  
  181.  
  182.  
  183.  
  184.  
  185. # ----------- REVISION HISTORY ------------
  186. # $Log: mapfindnonintegralfaces.py,v $
  187. # Revision 1.5  2003/03/24 08:57:15  cdunde
  188. # To update info and link to infobase
  189. #
  190. # Revision 1.4  2003/03/21 06:28:52  cdunde
  191. # To correct typo error
  192. #
  193. # Revision 1.2  2003/01/02 22:36:26  tiglari
  194. # transferred from rel-c63a branch
  195. #
  196. # Revision 1.1.2.1  2003/01/01 06:54:10  tiglari
  197. # added to 6.3 in spite of feature-freeze, due to importance
  198. #
  199. #
  200.